﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Net;
using System.Xml;
using System.ServiceModel;
using Out2Share.SharepointCopy;
using Out2Share.SharepointLists;
using Out2Share.SharepointWebs;
using Out2Share.SharepointSiteData;
using System.ServiceModel.Channels;
using System.Globalization;
using System.ServiceModel.Activation;
using System.Web;
using System.Net.Http;

namespace Out2Share
{
    public class SharepointHelper
    {
        public static ListsSoapClient GetListsSoapClient(ConfData conf, string site)
        {
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            basicHttpBinding.MaxReceivedMessageSize = 2147483647;
            basicHttpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
            basicHttpBinding.UseDefaultWebProxy = true;
            EndpointAddress endpoint = new EndpointAddress(site + "/_vti_bin/lists.asmx");
            if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("https", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
            }
            else if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            }
            ListsSoapClient client = new ListsSoapClient(basicHttpBinding, endpoint);
            if (conf.ht["CONFIGURATION_AUTH"] == "win")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
            }
            if (conf.ht["CONFIGURATION_AUTH"] == "basic")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(conf.ht["CONFIGURATION_USER_NAME"],
                                                                                                    conf.ht["CONFIGURATION_USER_PWD"]);
                
            }
            client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            if (conf.ht["CONFIGURATION_PROXY_SET"] == "true")
            {
                System.Net.WebProxy proxyObject = new System.Net.WebProxy(conf.ht["CONFIGURATION_PROXY_ADDRESS"]);
                proxyObject.Credentials = new System.Net.NetworkCredential(conf.ht["CONFIGURATION_PROXY_USER"],
                                                                           conf.ht["CONFIGURATION_PROXY_PWD"]);
                System.Net.WebRequest.DefaultWebProxy = proxyObject;
            }

            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                delegate(Object obj, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                System.Security.Cryptography.X509Certificates.X509Chain chain,
                System.Net.Security.SslPolicyErrors errors)
                {
                    return true;
                };
            if (conf.ht["CONFIGURATION_AUTH"] == "msonline")
            {
                string s = site + "/";
                s = s.Substring(0, s.Substring(10).IndexOf("/")+10);
                MsOnlineClaimsHelper helper = new MsOnlineClaimsHelper(
                        conf.ht["CONFIGURATION_USER_NAME"],
                        conf.ht["CONFIGURATION_USER_PWD"],
                        s + "/");
                basicHttpBinding.AllowCookies = true;
                var cookieManager1 = client.InnerChannel.GetProperty<IHttpCookieContainerManager>();
                cookieManager1.CookieContainer = helper.CookieContainer;

            }

            return client;
        }
        public static WebsSoapClient GetWebsSoapClient(ConfData conf, string site)
        {
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            basicHttpBinding.MaxReceivedMessageSize = 2147483647;
            basicHttpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
            basicHttpBinding.UseDefaultWebProxy = true;
            EndpointAddress endpoint = new EndpointAddress(site + "/_vti_bin/webs.asmx");
            if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("https", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
            }
            else if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            }
            WebsSoapClient client = new WebsSoapClient(basicHttpBinding, endpoint);
            if (conf.ht["CONFIGURATION_AUTH"] == "win")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
                
            }
            if (conf.ht["CONFIGURATION_AUTH"] == "basic")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(conf.ht["CONFIGURATION_USER_NAME"],
                                                                                                    conf.ht["CONFIGURATION_USER_PWD"]);
            }
            client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;

            if (conf.ht["CONFIGURATION_PROXY_SET"] == "true")
            {
                System.Net.WebProxy proxyObject = new System.Net.WebProxy(conf.ht["CONFIGURATION_PROXY_ADDRESS"]);
                proxyObject.Credentials = new System.Net.NetworkCredential(conf.ht["CONFIGURATION_PROXY_USER"],
                                                                           conf.ht["CONFIGURATION_PROXY_PWD"]);
                System.Net.WebRequest.DefaultWebProxy = proxyObject;
            }

            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                delegate(Object obj, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                System.Security.Cryptography.X509Certificates.X509Chain chain,
                System.Net.Security.SslPolicyErrors errors)
                {
                    return true;
                };
            if (conf.ht["CONFIGURATION_AUTH"] == "msonline")
            {
                string s = site + "/";
                s = s.Substring(0, s.Substring(10).IndexOf("/") + 10);
                MsOnlineClaimsHelper helper = new MsOnlineClaimsHelper(
                        conf.ht["CONFIGURATION_USER_NAME"],
                        conf.ht["CONFIGURATION_USER_PWD"],
                        s+"/" );
                basicHttpBinding.AllowCookies = true;
                var cookieManager1 = client.InnerChannel.GetProperty<IHttpCookieContainerManager>();
                cookieManager1.CookieContainer = helper.CookieContainer ;
                
            }
            return client;
        }
        public static CopySoapClient GetCopySoapClient(ConfData conf, string site)
        {
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            basicHttpBinding.MaxReceivedMessageSize = 2147483647;
            basicHttpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
            basicHttpBinding.UseDefaultWebProxy = true;
            EndpointAddress endpoint = new EndpointAddress(site + "/_vti_bin/copy.asmx");
            if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("https", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
            }
            else if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            }
            CopySoapClient client = new CopySoapClient(basicHttpBinding, endpoint);
            if (conf.ht["CONFIGURATION_AUTH"] == "win")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
            }
            if (conf.ht["CONFIGURATION_AUTH"] == "basic")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(conf.ht["CONFIGURATION_USER_NAME"],
                                                                                                    conf.ht["CONFIGURATION_USER_PWD"]);
            }
            client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            if (conf.ht["CONFIGURATION_PROXY_SET"] == "true")
            {
                System.Net.WebProxy proxyObject = new System.Net.WebProxy(conf.ht["CONFIGURATION_PROXY_ADDRESS"]);
                proxyObject.Credentials = new System.Net.NetworkCredential(conf.ht["CONFIGURATION_PROXY_USER"],
                                                                           conf.ht["CONFIGURATION_PROXY_PWD"]);
                System.Net.WebRequest.DefaultWebProxy = proxyObject;
            }

            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                delegate(Object obj, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                System.Security.Cryptography.X509Certificates.X509Chain chain,
                System.Net.Security.SslPolicyErrors errors)
                {
                    return true;
                };
            if (conf.ht["CONFIGURATION_AUTH"] == "msonline")
            {
                string s = site + "/";
                s = s.Substring(0, s.Substring(10).IndexOf("/") + 10);
                MsOnlineClaimsHelper helper = new MsOnlineClaimsHelper(
                        conf.ht["CONFIGURATION_USER_NAME"],
                        conf.ht["CONFIGURATION_USER_PWD"],
                        s + "/");
                basicHttpBinding.AllowCookies = true;
                var cookieManager1 = client.InnerChannel.GetProperty<IHttpCookieContainerManager>();
                cookieManager1.CookieContainer = helper.CookieContainer;

            }

            return client;
        }
        public static SiteDataSoapClient GetSiteDataClient(ConfData conf, string site)
        {
            BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
            basicHttpBinding.MaxReceivedMessageSize = 2147483647;
            basicHttpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
            basicHttpBinding.UseDefaultWebProxy = true;
            EndpointAddress endpoint = new EndpointAddress(site + "/_vti_bin/SiteData.asmx");
            if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("https", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.Transport;
            }
            else if (conf.ht["CONFIGURATION_ENDPOINT_NAME"].StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
            {
                basicHttpBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            }
            SiteDataSoapClient client = new SiteDataSoapClient(basicHttpBinding, endpoint);
            if (conf.ht["CONFIGURATION_AUTH"] == "win")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = System.Net.CredentialCache.DefaultNetworkCredentials;
            }
            if (conf.ht["CONFIGURATION_AUTH"] == "basic")
            {
                basicHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
                client.ChannelFactory.Credentials.Windows.ClientCredential = new NetworkCredential(conf.ht["CONFIGURATION_USER_NAME"],
                                                                                                    conf.ht["CONFIGURATION_USER_PWD"]);
            }
            client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
            if (conf.ht["CONFIGURATION_PROXY_SET"] == "true")
            {
                System.Net.WebProxy proxyObject = new System.Net.WebProxy(conf.ht["CONFIGURATION_PROXY_ADDRESS"]);
                proxyObject.Credentials = new System.Net.NetworkCredential(conf.ht["CONFIGURATION_PROXY_USER"],
                                                                           conf.ht["CONFIGURATION_PROXY_PWD"]);
                System.Net.WebRequest.DefaultWebProxy = proxyObject;
            }

            System.Net.ServicePointManager.ServerCertificateValidationCallback =
                delegate(Object obj, System.Security.Cryptography.X509Certificates.X509Certificate certificate,
                System.Security.Cryptography.X509Certificates.X509Chain chain,
                System.Net.Security.SslPolicyErrors errors)
                {
                    return true;
                };
            if (conf.ht["CONFIGURATION_AUTH"] == "msonline")
            {
                string s = site + "/";
                s = s.Substring(0, s.Substring(10).IndexOf("/") + 10);
                MsOnlineClaimsHelper helper = new MsOnlineClaimsHelper(
                        conf.ht["CONFIGURATION_USER_NAME"],
                        conf.ht["CONFIGURATION_USER_PWD"],
                        s + "/");
                basicHttpBinding.AllowCookies = true;
                var cookieManager1 = client.InnerChannel.GetProperty<IHttpCookieContainerManager>();
                cookieManager1.CookieContainer = helper.CookieContainer;

            }

            return client;
        }
        /// <summary>
        /// NOTE:Not used. Prefer UploadFile() with webservice
        /// </summary>
        /// <param name="url"></param>
        /// <param name="filename"></param>
        /// <param name="content"></param>
        public static void PutDoc(ConfData conf, string url, string filename, byte[] content)
        {
            WebClient wc = new WebClient();
            wc.Credentials = CredentialCache.DefaultNetworkCredentials;
            wc.UploadData(url + "/" + filename, "PUT", content);
            ListsSoapClient listService = GetListsSoapClient(conf, url);
        }

        public static void UploadFile(ConfData conf,string site, string listName, 
                string subject,string from, string to, DateTime date, string fileName, string currentFolder, byte[] fileBytes)
        {

            List<FieldInformation> fields = new List<FieldInformation>();
            FieldInformation fieldInfo;

            fieldInfo = new FieldInformation();
            fieldInfo.Id = new Guid();
            fieldInfo.DisplayName = "Subject";
            fieldInfo.Type = FieldType.Text;
            fieldInfo.InternalName = "Subject";
            fieldInfo.Value = subject;
            fields.Add(fieldInfo);

            fieldInfo = new FieldInformation();
            fieldInfo.Id = new Guid();
            fieldInfo.DisplayName = "From";
            fieldInfo.Type = FieldType.Text;
            fieldInfo.InternalName = "From";
            fieldInfo.Value = from;
            fields.Add(fieldInfo);

            fieldInfo = new FieldInformation();
            fieldInfo.Id = new Guid();
            fieldInfo.DisplayName = "To";
            fieldInfo.Type = FieldType.Text;
            fieldInfo.InternalName = "To";
            fieldInfo.Value = to;
            fields.Add(fieldInfo);

            fieldInfo = new FieldInformation();
            fieldInfo.Id = new Guid();
            fieldInfo.DisplayName = "Date";
            fieldInfo.Type = FieldType.DateTime;
            fieldInfo.InternalName = "Date";
            fieldInfo.Value = date.ToString("yyyy-MM-ddTHH:mm:ssZ",new CultureInfo("en-US"));
            fields.Add(fieldInfo);

            fieldInfo = new FieldInformation();
            fieldInfo.Id = new Guid();
            fieldInfo.DisplayName = "Folder";
            fieldInfo.Type = FieldType.Text;
            fieldInfo.InternalName = "Folder";
            fieldInfo.Value = currentFolder; 
            fields.Add(fieldInfo);
            
            string[] url;
            string[] BadCharacters = {"\\", "/", ":", "*", "?", "\"", "<", ">", "|", "#", "{", "}", "%" , "~", "&"};
            string[] GoodCharacters = {"", "", "", "", "", "", "", "", "", "", "", "", "" , "", ""};
            fileName = System.Text.RegularExpressions.Regex.Replace(fileName, "[\\/:*?\"<>|#{}%~&]", "");
            url = new string[] { string.Format("{0}/{1}/{2}", site, listName, Uri.EscapeUriString(fileName)) };
            CopyResult[] result;
            CopySoapClient service = GetCopySoapClient(conf, site);
            uint documentId = service.CopyIntoItems(site, url, fields.ToArray(), fileBytes, out result);
        }

    }
    
}
